package com.jboost.common.aspect;

import com.alibaba.fastjson.JSONObject;
import com.jboost.common.api.CommonAPI;
import com.jboost.common.aspect.annotation.BusinessPermissions;
import com.jboost.common.constant.CommonConstant;
import com.jboost.common.exception.JBoostException;
import com.jboost.common.util.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Arrays;

@Aspect
@Component
@Slf4j
public class BusinessPermissionsAspect {

    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private CommonAPI commonAPI;

    @Around("execution(public * com.jboost.modules..*.*Controller.*(..)) && (within(@com.jboost.common.aspect.annotation.BusinessPermissions *) || @annotation(com.jboost.common.aspect.annotation.BusinessPermissions) )")
    public Object before(ProceedingJoinPoint pjp) throws Throwable {
        Object target = pjp.getTarget();
        BusinessPermissions tp = target.getClass().getAnnotation(BusinessPermissions.class);
        if(null!=tp){
            log.debug("类名排除的租户{}",tp.banId());
        }else {
            MethodSignature signature = (MethodSignature) pjp.getSignature();
            // 1\. 获取被拦截的方法和方法名
            Method method = signature.getMethod();
            String methodName = signature.getDeclaringTypeName() + "." + signature.getName();
            log.debug("拦截方法{}", methodName);
            // 1.2 获取注解参数
            tp = method.getAnnotation(BusinessPermissions.class);
            log.debug("方法排除的租户{}",tp.banId());
        }
        // 2\. 获取当前线程的请求
        ServletRequestAttributes attribute = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attribute == null) {
            log.warn(this.getClass().getName() + "只能用于web controller方法");
            return pjp.proceed();
        }
        HttpServletRequest request = attribute.getRequest();
        String domain = request.getHeader(CommonConstant.DOMAIN);
        String businessId = request.getHeader(CommonConstant.BUSINESS_ID);
        log.debug("当前站点{}，机构{}",domain,businessId);
        if(StringUtils.isEmpty(businessId)){
            throw new JBoostException("机构参数不能为空！");
        }
        //禁止调用的租户
        if(StringUtils.isNotEmpty(tp.banId()) && tp.banId().equals(businessId)){
            throw new JBoostException(tp.message());
        }
        //指定可以调用的租户
        if(StringUtils.isNotEmpty(tp.customId()) && !tp.customId().equals(businessId)){
            throw new JBoostException(tp.message());
        }
        //不是运营的租户才判断状态
        if(!CommonConstant.OPERATION_TENANT.equals(businessId)){
            Object  businessStatus = redisUtil.get(businessId+"_status");
            if(null ==  businessStatus){
                JSONObject store = commonAPI.getBusinessById(businessId);
                if(null!=store){
                    String storeId = store.getString("id");
                    String storeStatus = store.getString("status");
                    redisUtil.set(storeId+"_status",storeStatus);
                     businessStatus = storeStatus;
                }
            }
            String [] status = tp.status();
            if(status.length > 0){
                if ( null ==  businessStatus || !Arrays.asList(status).contains( businessStatus.toString()) ){
                    log.debug("机构状态{}", businessStatus);
                    throw new JBoostException(tp.message());
                }
            }
        }
        return pjp.proceed();
    }
}
